Scroll to navigation

IOPRIO_SET(2) Руководство программиста Linux IOPRIO_SET(2)

ИМЯ

ioprio_get, ioprio_set - получает/устанавливает класс и приоритет планирования ввода-вывода

ОБЗОР

int ioprio_get(int which, int who);
int ioprio_set(int which, int who, int ioprio);

ОПИСАНИЕ

Системные вызовы ioprio_get() и ioprio_set(), соответственно, получают и устанавливают класс и приоритет планирования ввода-вывода одного или более процессов.

В аргументах which и who задаётся процесс(ы), над которым выполняются системные вызовы. Аргументом which задаётся смысл значения who; он может иметь одно из следующих значений:

В who указан идентификатор единственного процесса.
В who указан идентификатор группы процессов, учитываются члены группы процессов.
В who указан идентификатор пользователя, учитываются все процессы, которые имеют этот реальный идентификатор.

Если при вызове ioprio_get() в which указано IOPRIO_WHO_PGRP или IOPRIO_WHO_USER, и под шаблон who подходит более одного процесса, то возвращаемый приоритет будет равен самому высокому значению среди процессов этой группы. Считается, что один приоритет больше другого, если он принадлежит более высокому классу процессов (IOPRIO_CLASS_RT является самым высоким классом приоритетов; IOPRIO_CLASS_IDLE — самым низким), или если оба процесса принадлежат одному классу, то тогда самым высоким будет приоритет с большим уровнем (меньший номер приоритета, означает более высокий уровень).

Аргумент ioprio, задаваемый в ioprio_set(), является битовой маской, в которой указываются класс планирования и приоритет, назначаемый заданному процессу(ам). Для компоновки и разделения значений ioprio используются следующие макросы:

Этот макрос объединяет заданный класс планирования class и приоритет (data) в значение ioprio, которое возвращается как результат макроса.
Этот макрос из указанной маски mask (значение ioprio) возвращает значение класса ввода-вывода, то есть одно из значений: IOPRIO_CLASS_RT, IOPRIO_CLASS_BE или IOPRIO_CLASS_IDLE.
Этот макрос из указанной маски mask (значение ioprio) возвращает значение приоритета (data).

Подробней о классах планирования и приоритетах смотрите в разделе ЗАМЕЧАНИЯ.

Приоритеты ввода-вывода поддерживаются при операциях чтения и синхронной (O_DIRECT, O_SYNC) записи. Приоритеты ввода-вывода не поддерживаются при асинхронной записи, так как они вызываются вне контекста программы засоряющей память, и поэтому приоритеты программы не применяются.

ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ

При успешном выполнении ioprio_get() возвращается значение ioprio для процесса с самым высоким приоритетом ввода-вывода из всех процессов, подходящих под критерий, указанный в which и who. При ошибке возвращается -1, а в errno содержится код ошибки.

При успешном выполнении ioprio_set() возвращается 0. При ошибке возвращается -1, а в errno содержится код ошибки.

ОШИБКИ

Неправильное значение which или ioprio. Обратитесь к разделу ЗАМЕЧАНИЯ, в нём приведены доступные классы планировщика и уровни приоритета ioprio.
У вызывающего процесса нет прав, необходимых для назначения данного ioprio указанному процессу(ам). Более подробную информацию о необходимых правах ioprio_set() можно найти в разделе ЗАМЕЧАНИЯ.
Не найдено процессов, которые бы соответствовали заданным в which и who критериям.

ВЕРСИИ

Данные системные вызовы появились в Linux начиная с ядра версии 2.6.13.

СООТВЕТСТВИЕ СТАНДАРТАМ

Данные системные вызовы есть только в Linux.

ЗАМЕЧАНИЯ

В glibc нет обёрточной функции для этих системных вызовов; вызывайте их с помощью syscall(2).

Данные системные вызовы действительно работают, если используется планировщик ввода-вывода, поддерживающий приоритеты ввода-вывода. В ядре 2.6.17 такой планировщик только один: Completely Fair Queuing (CFQ).

Выбор планировщика ввода-вывода

Планировщики ввода-вывода устанавливаются в каждом устройстве через специальный файл /sys/block/<устройство>/queue/scheduler.

Используемый в данный момент планировщик ввода-вывода можно посмотреть через файловую систему /sys. Например, следующая команда покажет список всех планировщиков, загруженных в ядро:

$ cat /sys/block/hda/queue/scheduler
noop anticipatory deadline [cfq]

Планировщик, работающий на устройстве (в примере hda), указан в скобках. Замена планировщика выполняется с помощью записи имени нового планировщика в этот файл. Например, следующая команда установит планировщик cfq для устройства hda:

$ su
Пароль:
# echo cfq > /sys/block/hda/queue/scheduler

Планировщик ввода-вывода с полностью справедливой очерёдностью (CFQ)

Начиная с v3 (т.н. CFQ Time Sliced) в CFQ реализованы уровни nice для ввода-вывода, подобно используемым в планировщике ЦП. Эти уровни nice сгруппированы в три класса планирования, в каждом содержится один и более уровней приоритета:

Класс ввода-вывода реального времени. Данному классу планирования назначен самый высокий приоритет по сравнению с другими: процессам с этим классом всегда предоставляется первоочередной доступ к диску. Поэтому данный класс следует использовать с осторожностью: одним процессом ввода-вывода реального времени можно затормозить все остальные. В классе реального времени есть 8 уровней данных класса (приоритетов), которые уточняют сколько времени нужно процессу для работы с диском для каждого сервиса. Самый высокий уровень приоритета реального времени имеет значение 0; самый низкий — 7. В будущем это может измениться и можно будет непосредственно задавать желаемую скорость обмена данными с диском.
Класс лучшего из возможного (best-effort) планирования, устанавливается по умолчанию для всех процессов, которым не назначен определённый приоритет ввода-вывода. Данными класса (приоритет) определяется пропускная способность ввода-вывода процесса. Уровни приоритета данного класса аналогичны значениям nice для ЦП (см. getpriority(2)). Уровень приоритета определяет первоочерёдность относительно других процессов с классом лучшего из возможного планирования. Уровни приоритета находятся в диапазоне от 0 (самый высший) до 7 (самый низший).
Класс свободного (idle) планирования. Процессы, работающие с этим уровнем, получат время для ввода-вывода только когда нет обмена с диском процессов с другими классами. Свободный класс не имеет данных класса. Обратите внимание, что процесс с этим классом приоритета может испытывать нехватку ресурсов, если процессы с более высокими приоритетами постоянно обращаются к диску.

Более подробную информацию о планировщике ввода-вывода CFQ и пример программы можно найти в файле Documentation/block/ioprio.txt.

Необходимые права для установки приоритетов ввода-вывода

Право на изменение приоритета процесса зависит от двух условий:

Владелец процесса
Непривилегированный процесс может установить приоритет ввода-вывода только для процесса, чей реальный идентификатор совпадает с реальным или эффективным идентификатором вызывающего процесса. Процесс с мандатом CAP_SYS_NICE может изменять приоритет любого процесса.
Требуемый приоритет
Попытка установить очень высокий приоритет (IOPRIO_CLASS_RT) требует мандата CAP_SYS_ADMIN. Ядра версий до 2.6.24 также требуют мандата CAP_SYS_ADMIN для установки очень низкого приоритета (IOPRIO_CLASS_IDLE), но начиная с Linux 2.6.25 это отменено.

Вызов ioprio_set() должен соблюдать оба правила, или он завершится с ошибкой EPERM.

ДЕФЕКТЫ

В glibc пока нет заголовочного файла, определяющего прототип и макросы, описанные в этой странице. Нужные определения можно найти в linux/ioprio.h.

СМОТРИТЕ ТАКЖЕ

getpriority(2), open(2), capabilities(7)

Файл Documentation/block/ioprio.txt из дерева исходного кода ядра.

2008-07-09 Linux